/**
 * Copyright (c) 2010-2011 julewa.com.  
 * All rights reserved. 
 * 
 * @author Huang Benhua
 * @date 2011-2-20
 * 
**/
package com.julewa.db.ibatis;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.julewa.ThreadValue;
import com.julewa.db.BeanInfo;
import com.julewa.db.Transaction;

public final class IbatisTransaction implements Transaction{
	private @Autowired Ibatis ibatis;
	//
	private SqlMapClient sqlMap = null;
	private Map<Class<?>, String> namespaces = null;
	public IbatisTransaction(){}
	
	@SuppressWarnings("unused")
	@PostConstruct
	private void init(){
		sqlMap = ibatis.getSqlMap();
		setBeans(ibatis.getBeans());
	}
	private ThreadValue<Boolean> status = new ThreadValue<Boolean>(); 
	// 
	private void setBeans(Map<String, BeanInfo> vbeans) {
		namespaces = new HashMap<Class<?>, String>();
		for(BeanInfo b:vbeans.values()){
			namespaces.put(b.getTypeClass(), b.getCode());
		}
	}
	//
	public <T> String getNamespace(Class<T> clazz){
		return namespaces.get(clazz);
	};
	//
	public final boolean inProgress(){
		return null != status.get();
	}
	
	public final boolean isAutomatic(){
		return null == status.get();
	}
	
	public final void start(){
		if(status.get()!= null)return;
		status.set(Boolean.TRUE);
		try {
			sqlMap.startTransaction();
		} catch (SQLException e) {
			status.set(null);
			throw new RuntimeException("[iBatis.transaction.start]", e);
		}
	}
	
	public final void commit(){
		try {
			sqlMap.commitTransaction();
		} catch (SQLException e) {
			throw new RuntimeException("[iBatis.transaction.commit]", e);
		}
	}
	
	public final void rollback(){
		
	}
	
	public final void stop(){
		try {
			sqlMap.endTransaction();
		} catch (SQLException e) {
			throw new RuntimeException("[iBatis.transaction.stop]", e);
		}finally{
			status.set(null);
		}
	}
	

	@SuppressWarnings("unused")
	@Autowired(required=false)
	private void setIbatisLoader(IbatisTestLoader loader){
		this.sqlMap = loader.getSqlMapClient();
	}
	
}
